package com.zdsoft.site.zookeeper;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestZookeeper implements Watcher {

	private Logger logger=LoggerFactory.getLogger(getClass());
	@Test
	public void test() throws IOException, KeeperException, InterruptedException {
		//连接集群服务器
		//zk的优点之一，就是高可用性，上面的代码连接的是单台zk server，如果这台server挂了，自然代码就会出错，事实上zk的API考虑到了这一点，把连接代码改成下面这样：
		ZooKeeper zk = new ZooKeeper("192.168.34.115:2181,192.168.34.115:2182,192.168.34.115:2183", 300000, this);//连接zk server
		String znode="/p2p";
		Stat stat=zk.exists(znode, true);
		if(null==stat){
			//创建节点
			String createResult = zk.create(znode, "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
			logger.debug("创建结果:{}",createResult);
		}
		//获取节点的值
        byte[] b = zk.getData(znode, false, stat);
        logger.debug(new String(b));
        zk.close();
	}
	/**
	 *  即：IP1:port1,IP2:port2,IP3:port3...  用这种方式连接集群就行了，只要有超过半数的zk server还活着，应用一般就没问题。但是也有一种极罕见的情况，
	 *  比如这行代码执行时，刚初始化完成，正准备连接ip1时，因为网络故障ip1对应的server挂了，仍然会报错（此时，zk还来不及选出新leader），这个问题详见：
	 *  http://segmentfault.com/q/1010000002506725/a-1020000002507402，参考该文的做法，改成：
	 *  但是这样代码未免太冗长，建议用开源的zkClient，官方地址: https://github.com/sgroschupf/zkclient，使用方法很简单：见如下方法testZkClient
	 * @throws IOException
	 */
	@Test
	public void test2() throws IOException{
		ZooKeeper zk = new ZooKeeper("192.168.34.115:2181,192.168.34.115:2182,192.168.34.115:2183", 300000, this);//连接zk server
        if (!zk.getState().equals(ZooKeeper.States.CONNECTED)) {
            while (true) {
                if (zk.getState().equals(ZooKeeper.States.CONNECTED)) {
                    break;
                }
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
	}
	//这种方案目前已经不行了
	@Test
    public void testZkClient() {
        ZkClient zkClient = new ZkClient("192.168.34.115:2181,192.168.34.115:2182,192.168.34.115:2183");
        String node = "/p2p";
        if (!zkClient.exists(node)) {
            zkClient.createPersistent(node, "hello zk");
        }
        logger.debug("{}",zkClient.readData(node));
    }
	@Override
	public void process(WatchedEvent event) {
		logger.debug("event:{}",event);
	}

}
